
import java.io.ByteArrayInputStream;

import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

import downloader.*;


public class midlet extends MIDlet implements CommandListener, DownloadListener {
	private static Display display = null;
	private static Form	form = null;
	
	private DownloadManager manager = null;
	private TextField urlField = null;
	
	private Command download = null;
	private Command analyze = null;
	private Command exit = null;
	private Command anamethod = null;
	private Command newDownload = null;

	private ChoiceGroup group = null;
	private classAnalyze classAnalyze = null;
	
	public midlet() {
		this.setDisplay(Display.getDisplay(this));
		this.startDownloader();
	}

	/* (non-Javadoc)
	 * @see javax.microedition.midlet.MIDlet#startApp()
	 */
	protected void startApp() throws MIDletStateChangeException {
		getDisplay().setCurrent(form);
	}
	/* (non-Javadoc)
	 * @see javax.microedition.midlet.MIDlet#destroyApp(boolean)
	 */
	protected void destroyApp(boolean unconditional)
			throws MIDletStateChangeException {}

	/* (non-Javadoc)
	 * @see javax.microedition.midlet.MIDlet#pauseApp()
	 */
	protected void pauseApp() {}
	
	
	private void startDownloader() {
		this.setForm(new Form("Analyze ClassFile"));
		getForm().setCommandListener(this);
		getForm().setTitle("Download Class-File");
		this.urlField = new TextField("URL zur Class-File:", "http://pcc-praktikum.googlecode.com/svn/trunk/PCC/ClassA.class", 350, TextField.ANY);
		getForm().append(urlField);
		
		this.download = new Command("Download", Command.SCREEN, 1);
		this.exit = new Command("Exit", Command.EXIT, 1);
		getForm().addCommand(this.download);
		getForm().addCommand(this.exit);
		
		this.manager = new DownloadManager();
		this.manager.addListener(this);
	}
	
	/* (non-Javadoc)
	 * @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command, javax.microedition.lcdui.Displayable)
	 */
	public void commandAction(Command c, Displayable d) {
		if (c == this.download) {
			getForm().deleteAll();
			this.manager.download(this.urlField.getString());	
		} else {
			if (c == this.exit) {
				this.notifyDestroyed();
			}
			else {
				if (c == this.analyze) {
					getForm().deleteAll();
					this.analyzeByteCode();
				}
				else {
					if (c == this.anamethod) {
						getForm().deleteAll();					
						this.analyzeSubApp();
					}
					else {
						if (c == this.newDownload) {
							getForm().deleteAll();						
							this.startDownloader();
							try {
								this.startApp();
							} catch (MIDletStateChangeException e) {
								e.printStackTrace();
							}
						}
					}
				}
			}
		}
		
	}

	public void downloadCompleted(byte[] data) {
		ByteArrayInputStream stream = new ByteArrayInputStream(data);
		this.classAnalyze = new classAnalyze(stream);
		
		try{
			this.classAnalyze.read();
			
			StringItem text = new StringItem("Download Completed!\n\r", "Die Class-File wurde erfolgreich heruntergeladen.\n\rDie Klasse kann nun analyziert werden.");
			getForm().append(text);
			getForm().removeCommand(this.download);			

			this.analyzeSubApp();
		}
		catch(Exception e) {
			StringItem text = new StringItem("Download fehlgeschlagen!\n\r", "Die Class-File konnte nicht heruntergeladen werden.");
			getForm().append(text);		
			getForm().removeCommand(this.download);	
			this.newDownload = new Command("New Download", Command.SCREEN, 1);
			getForm().addCommand(this.newDownload);
		}	
	}
	
	private void analyzeSubApp() {
		getForm().removeCommand(newDownload);
		getForm().removeCommand(anamethod);
		this.analyze = new Command("Analyze", Command.SCREEN, 1);
		getForm().addCommand(this.analyze);
		this.setChoiceMethodGroup();
		
	}
	
	private void setChoiceMethodGroup() {
		String readMethods[] = classAnalyze.getMethods();
		if(readMethods.length>0) {
			this.group = new ChoiceGroup("Wähle eine Methode", 1);
			for(int i = 0; i < readMethods.length; i++) {
				this.group.append(readMethods[i],null);
			}
			getForm().append(group);
		}
	}
	
	private void analyzeByteCode() {
		String method = getSelectedMethod();
		if(method!=null) {
			this.classAnalyze.setReadMethod(method);
			if(this.classAnalyze.analyzeCode()==1) {
				
				StringItem text =  null;
				text = new StringItem("Analyse von "+method+" erfolgreich\n\r","Lokale Variablen werden "+classAnalyze.getReadVarCount()+"-Mal gelesen und "+classAnalyze.getWriteVarCount()+"-Mal geschrieben");
				getForm().append(text);
				getForm().removeCommand(this.analyze);
				
				this.newDownload = new Command("New Download", Command.SCREEN, 1);
				getForm().addCommand(this.newDownload);
				this.anamethod = new Command("Analyze methods", Command.SCREEN, 1);
				getForm().addCommand(this.anamethod);
				
			}
		}
		
	}
	
	private String getSelectedMethod() {
		if(this.group!=null) {
			return this.group.getString(this.group.getSelectedIndex());
		}
		return null;
	}
	
	public void downloadError(Exception e) {
		StringItem text = new StringItem("Download fehlgeschlagen!\n\r", "Die Class-File konnte nicht heruntergeladen werden.");
		getForm().append(text);		
		getForm().removeCommand(this.download);	
		this.newDownload = new Command("New Download", Command.SCREEN, 1);
		getForm().addCommand(this.newDownload);
	}

	public void downloadStatus(int percent) {
		getForm().setTitle("Download " + percent + " %...");
	}

	public void setForm(Form formular) {
		form = formular;
	}

	public static Form getForm() {
		return form;
	}
	public void setDisplay(Display disp) {
		display = disp;
	}

	public static Display getDisplay() {
		return display;
	}
}
